﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Search.Administration;
using Microsoft.Office.Server.Search.Query;
using System.Data;
using MS.InformationManagement.Core.Support;
using Microsoft.SharePoint.Taxonomy;
using MS.InformationManagement.Support;
using MS.InformationManagement.Core.RecordSiteQuery;
using MS.InformationManagement.DAL.RecordCenter;
using MS.InformationManagement.Support.Constants;
using MS.InformationManagement.DAL.DTOs;
using MS.InformationManagement.DAL.DocumentCenter;

namespace MS.InformationManagement.BLL.DocumentPrinter
{
    public class DocumentDeliveryBagBLL
    {

        public static IEnumerable<Zona> GetDeliveryZones()
        { 
            using(var dc =  new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                return (from item in dc.Zonas
                        orderby item.Title ascending
                        select item);
            }
        }

        public static Planilla GetDeliveryForm(int selectedDeliveryMean, string SelectedZone)
        {

            Planilla deliveryForm = new Planilla();

            using (var dc = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                //Getting delivery entities
                var selectedItems =(from item in dc.EnviosDeCorreo
                                    where item.NombreZona == SelectedZone &&
                                          item.Enviado == false
                                    select item);

                //Getting delivery mean
                var deliveryMean =(from mean in dc.MediosDeEnvio
                                   where mean.Id == selectedDeliveryMean
                                   select mean).FirstOrDefault();
 
                //Setting delivery form data
                deliveryForm.EnvioPlanilla = deliveryMean;
                foreach(var entity in selectedItems)
                    deliveryForm.Envios.Add(entity);

                return deliveryForm;
            }
        }

        public static List<DeliveryFormDTO> GetDeliveryRows(Planilla deliveryForm)
        {
            List<DeliveryFormDTO> _rows = new List<DeliveryFormDTO>();
            _rows = (from item in deliveryForm.Envios
                     select new DeliveryFormDTO()
                     {
                         Id = item.Id.ToString(),
                         ModoEnvio = item.MedioEnvioCorreo.Title,
                         Destinatario = item.RemitenteDestinatario,
                         Ciudad = item.City.Label,
                         Direccion = item.Dirección,
                         Peso = item.PesoCorrespondencia.ToString(),
                         Costo = Convert.ToInt64(item.CostoDelEnvío)
                     }).ToList();

            return _rows;

        }

        public static IEnumerable<DocumentoImpreso> GetDocumentsForCaptureAndWeighUp(string docCriteria, string areaCriteria, int pageIndex, int pageSize, out int totalRecords, int? userFilterId)
        {
            int startRow = pageIndex * pageSize;
            totalRecords = 0;
            IEnumerable<DocumentoImpreso> foundDocuments = null;
            string query = getCamlQuery(docCriteria, areaCriteria, userFilterId);
            SPQuery camlQuery = new SPQuery() { Query = query };
            SPListItemCollection results = SPContext.Current.Web.Lists[GlobalConstants.LIST_DOCUMENTOS_VENTANILLA].GetItems(camlQuery);
            totalRecords = results.Count;
            foundDocuments = getPrintedEntities(results, startRow, pageSize);
            return foundDocuments;
        }
        
        public static IEnumerable<DocumentoImpreso> GetDeliveryBagDocuments(string docCriteria, string areaCriteria, int pageIndex, int pageSize, out int totalRecords, int? userFilterId)
        {
            int startRow = pageIndex * pageSize;
            totalRecords = 0;
            IEnumerable<DocumentoImpreso> foundDocuments = new List<DocumentoImpreso>();
            string query = getCamlQuery(docCriteria, areaCriteria, userFilterId);
            SPQuery camlQuery = new SPQuery() { Query = query };
            SPListItemCollection results = SPContext.Current.Web.Lists[GlobalConstants.LIST_DOCUMENTOS_IMPRESOS].GetItems(camlQuery);
            totalRecords = results.Count;
            if (totalRecords == 0)
                return foundDocuments;
            foundDocuments = getPrintedEntitiesToReception(results, startRow, pageSize);
            return foundDocuments;
        }


        public static List<EnvíoDeCorrespondencia>  GetDocumentsForShippingDelivery(int pageIndex, int pageSize, out int totalRecords)
        {
            int startRow = pageIndex * pageSize;
            totalRecords = 0;
            using (var dc = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                var deliveryItems = (from item in dc.EnviosDeCorreo
                                     where  item.Enviado.HasValue && item.Enviado.Value == false
                                     orderby item.MedioEnvioCorreo.Title ascending
                                     select item).Skip(startRow).Take(pageSize);
                totalRecords = deliveryItems.Count();
                return deliveryItems.ToList();
            }

        }


        public static IEnumerable<MedioDeEnvio> GetDeliveryMeans()
        {
            IEnumerable<MedioDeEnvio> foundEntities = null;
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                foundEntities = ctx.MediosDeEnvio.OrderBy(dm => dm.Title);
            }
            return foundEntities;
        }

        public static System.Collections.Generic.IEnumerable<SeccionDTO> GetArea(string searchCriteria)
        {
            IEnumerable<Seccion> foundElements = QueryRecordsSiteHelper<Seccion>.QueryRecordsEntitiesSite(GlobalConstants.LIST_BIBLIOTECA_SECCION,
                string.Format("<Where><BeginsWith><FieldRef Name='Title' /><Value Type='Text'>{0}</Value></BeginsWith></Where>", searchCriteria),
                new Nullable<uint>());
            foreach (Seccion entity in foundElements)
            {
                yield return new SeccionDTO { Id = entity.Id.Value, Title = entity.Title };
            }
        }

        private static string getCamlQuery(string docCriteria, string areaCriteria, int? userFilterId)
        {
            List<string> views = new List<string>();
            List<string> values = new List<string>();
            List<string> Operators = new List<string>();
            List<string> type = new List<string>();

            if (!string.IsNullOrEmpty(docCriteria))
            {
                views.Add(CustomSiteColumns.FIELD_DOCSET_ID_RADICADO);
                values.Add(docCriteria);
                type.Add("Text");
                Operators.Add("Eq");
            }

            if (!string.IsNullOrEmpty(areaCriteria))
            {
                views.Add(CustomSiteColumns.FIELD_OWNER_DEPTO);
                values.Add(areaCriteria);
                type.Add("Text");
                Operators.Add("Eq");
            }

            if (userFilterId.HasValue)
            {
                views.Add(CustomSiteColumns.FIELD_SP_CREATED_BY);
                values.Add(userFilterId.Value.ToString());
                type.Add("userid");
                Operators.Add("userid");
            }

            string _temp = string.Empty;
            string caml = CamlHelper.CreateCAMLQuery(values.ToArray(), views.ToArray(), type.ToArray(), Operators.ToArray(), ref _temp);
            return caml;
        }

        private static List<DocumentoImpreso> getPrintedEntities(SPListItemCollection items, int startRow, int pageSize)
        {
            List<DocumentoImpreso> printedDocuments = new List<DocumentoImpreso>();
            foreach (SPListItem item in items)
            {
                var documento = new DocumentoImpreso();
                documento.AreaDelDocumento = item[CustomSiteColumns.FIELD_OWNER_DEPTO] == null ? string.Empty : item[CustomSiteColumns.FIELD_OWNER_DEPTO].ToString();
                documento.IdDocumento = Convert.ToDouble(item[CustomSiteColumns.FIELD_PRINTED_DOC_ID]);
                documento.NoRadicado = item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO].ToString();
                documento.BibliotecaDelDocumento = item[CustomSiteColumns.FIELD_PRINTED_LIBRARY] == null ? string.Empty : item[CustomSiteColumns.FIELD_PRINTED_LIBRARY].ToString();
                documento.Created = Convert.ToDateTime(item[SPBuiltInFieldId.Created].ToString());
                documento.Asunto = item[CustomSiteColumns.FIELD_DOCSET_ASUNTO] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_ASUNTO].ToString();
                documento.TipoDocumento = item[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE].ToString();
                documento.RemitenteDestinatario = item[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString();
                documento.Id = item.ID;
                documento.Pais = item[CustomSiteColumns.FIELD_DOCUMENT_COUNTRY] as TaxonomyFieldValue;
                SPFieldLookupValueCollection references = item[CustomSiteColumns.FIELD_WINDOW_RECEIVED_DELIVERY] as SPFieldLookupValueCollection;
                if (references != null)
                    documento.DeliveryInfo = getDeliveryInfo(references, item, new Nullable<int>()); 
                printedDocuments.Add(documento);
                var copies = getPrintedCopyEntities(item[CustomSiteColumns.FIELD_PRINTED_LIBRARY].ToString(), Convert.ToInt16(item[CustomSiteColumns.FIELD_PRINTED_DOC_ID]), SPContext.Current.Web, item);
                if (copies.Count() > 0)
                    printedDocuments.AddRange(copies);
            }

            return printedDocuments;
        }

        private static EnvíoDeCorrespondencia getDeliveryInfo(SPFieldLookupValueCollection lookUpValues, SPItem item, int? copyItemId)
        {
            EnvíoDeCorrespondencia entity;
            string bibliotecaDocumento = item[CustomSiteColumns.FIELD_PRINTED_LIBRARY].ToString();
            int idDoc = 0;
            if(copyItemId != null && copyItemId.HasValue && copyItemId.Value != 0)
                idDoc = copyItemId.Value;
            else
                idDoc = Convert.ToInt16(item[CustomSiteColumns.FIELD_PRINTED_DOC_ID]);

            using(var dc = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                entity = (from itemCorreo in dc.EnviosDeCorreo
                          from reference in lookUpValues.OfType<SPFieldLookupValue>()
                          where itemCorreo.Id.Value == reference.LookupId &&
                                itemCorreo.Title.Trim() == reference.LookupValue.Trim() &&
                                itemCorreo.BibliotecaDelDocumento.Trim() == bibliotecaDocumento.Trim() &&
                                Convert.ToInt16(itemCorreo.IdDocumento) == idDoc
                          select itemCorreo).FirstOrDefault();
            }

            return entity;
        }


        private static IEnumerable<DocumentoImpreso> getPrintedCopyEntities(string library, int rootDocumentId, SPWeb currentWeb, SPListItem parenItem)
        {
            SPFolder rootEntity = currentWeb.Lists[library].GetItemById(rootDocumentId).Folder;
            SPQuery query = new SPQuery();
            query.Folder = rootEntity;
            query.Query = string.Format("<Where><Eq><FieldRef Name='ContentType' /><Value Type='Text'>{0}</Value></Eq></Where>",GlobalConstants.CTTN_COPIAS_RADICADO);
            SPListItemCollection copiesItem = currentWeb.Lists[library].GetItems(query);
            SPFieldLookupValueCollection parentReferences = parenItem[CustomSiteColumns.FIELD_WINDOW_RECEIVED_DELIVERY] as SPFieldLookupValueCollection;

            foreach (SPListItem copy in copiesItem)
            {
                yield return new DocumentoImpreso()
                {
                    AreaDelDocumento = RadicadosHelper.GetUserSeccionName(rootEntity.Item[CustomSiteColumns.FIELD_DOCUMENT_DEPARTMENT].ToString()),
                    Asunto = rootEntity.Item[CustomSiteColumns.FIELD_DOCSET_ASUNTO].ToString(),
                    BibliotecaDelDocumento = library,
                    Created = Convert.ToDateTime(copy[SPBuiltInFieldId.Created]),
                    IdDocumento = copy.ID,
                    NoRadicado = rootEntity.Item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO].ToString(),
                    RemitenteDestinatario = copy[CustomSiteColumns.FLD_COPY_REPRESENTANTE] != null ? copy[CustomSiteColumns.FLD_COPY_REPRESENTANTE].ToString() : copy[CustomSiteColumns.FLD_COPY_NAME].ToString(),
                    TipoDocumento = rootEntity.Item[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE].ToString(),
                    Id = parenItem.ID,
                    DeliveryInfo = getDeliveryInfo(parentReferences,parenItem, copy.ID),
                    IsCopy = true
                };
            }
        }

        private static IEnumerable<DocumentoImpreso> getPrintedEntitiesToReception(SPListItemCollection items, int startRow, int pageSize)
        {
            var itemsPage = (from item in items.OfType<SPListItem>()
                             select new DocumentoImpreso()
                             {
                                 AreaDelDocumento = item[CustomSiteColumns.FIELD_OWNER_DEPTO] == null ? string.Empty : item[CustomSiteColumns.FIELD_OWNER_DEPTO].ToString(),
                                 IdDocumento = item.ID,
                                 NoRadicado = item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO].ToString(),
                                 BibliotecaDelDocumento = item[CustomSiteColumns.FIELD_PRINTED_LIBRARY] == null ? string.Empty : item[CustomSiteColumns.FIELD_PRINTED_LIBRARY].ToString(),
                                 Created = Convert.ToDateTime(item[SPBuiltInFieldId.Created].ToString()),
                                 Asunto = item[CustomSiteColumns.FIELD_DOCSET_ASUNTO] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_ASUNTO].ToString(),
                                 TipoDocumento = item[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE].ToString(),
                                 RemitenteDestinatario = item[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] == null ? string.Empty : item[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString()
                             }).Skip(startRow).Take(pageSize);
            return itemsPage;
        }
    }
}
